import axios from 'axios'
import AuthStorage from './storage.js'
import URLSearchParams from 'url-search-params'
import { md5 } from '@/utilities/crypto' // 加密
import { app } from '@/utilities/app'
import {
  RequestError,
  ResponseError,
  TokenInvalidError,
  RoleInUseError,
  AccountNameDuplicatedError,
  errorMap
} from './errors'

if (!window.URLSearchParamsURL) {
  window.URLSearchParams = URLSearchParams
}

function filterOutUndefined(obj) {
  const result = {}
  for (const key of Object.keys(obj)) {
    if (obj[key] !== undefined) {
      result[key] = obj[key]
    }
  }
  return result
}

function signature(data) {
  return md5(data)
}

export default async function request({
  url,
  method = 'GET',
  params = {},
  body = {},
  file,
  ...args
}) {
  params = filterOutUndefined(params)
  body = filterOutUndefined(body)
  let response
  let searchparams
  let dataparams
  if (file) {
    searchparams = new FormData()
    if (file.postKey) {
      searchparams.append(file.postKey, file.file)
    } else {
      searchparams.append('myfiles', file)
    }
  } else {
    searchparams = new window.URLSearchParams()
  }
  var  a = new Date();
  var btime= a .getTime();
  var signs = "data="+JSON.stringify(body)+"&stmb="+btime;
  searchparams.append('stmb', btime)
  searchparams.append('source', '03')
  searchparams.append('token', AuthStorage.token)
  searchparams.append('version', '')
  searchparams.append('data', JSON.stringify(body))
  searchparams.append('sign', signature(signs))

  var signs2 = "data="+JSON.stringify(params)+"&stmb="+btime;
  if (method === 'GET') {
    dataparams = {
      stmb:a.getTime(),
      source: '03',
      token: AuthStorage.token,
      version: '',
      data: JSON.stringify(params),
      sign: signature(signs2)
    }
  }
  try {
    response = await axios({
      url: '/ecshop' + url,
      // url: '/itravel/ecshop' + url,
      method,
      params: dataparams,
      data: searchparams,
      ...args
    })
  } catch (e) {
    const error = new RequestError(e.message)
    error.code = String(e.response.status)
    throw error
  }
  const { rspCode, rspMsg, data: rspData } = response.data
  if (rspCode === '0000') {
    return rspData
  } else {
    try {
      if (errorMap.has(rspCode)) {
        throw new (errorMap.get(rspCode))(rspMsg)
      } else {
        const error = new ResponseError(rspMsg)
        error.code = rspCode
        throw error
      }
    } catch (e) {
      if (e instanceof TokenInvalidError) {
        await app.$notify({ type: 'error', message: '请重新登录！' })
        app.$router.push({ name: 'login' })
        throw new Error('请重新登录！')
      } else if (e instanceof RoleInUseError) {
        throw new RoleInUseError()
      } else if (e instanceof AccountNameDuplicatedError) {
        throw new AccountNameDuplicatedError()
      } else {
        throw e
      }
    }
  }
}
